home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
JCSM Shareware Collection 1996 September
/
JCSM Shareware Collection (JCS Distribution) (September 1996).ISO
/
calcultr
/
fracti10.zip
/
FRACTION.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-06
|
6KB
|
295 lines
// General Fraction class - also handles Mixed Numbers & Decimals
// M\Cooper
// 3425 Chestnut Ridge Rd.
// Grantsville, MD 21536-9801
// --------------------------
// Email: thegrendel@aol.com
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 30
#define ARGCOUNT 4
#define OPERATOR_ERROR 5
#define WRONG_NO_OF_ARGS 2
#define MAXIMUM(x,y) (x>=y) ? x:y
#define SLASH '/'
#define DASH '-'
#define TERM1 argv[1]
#define OP *argv[2]
#define TERM2 argv[3]
#define POSITIVE 0
#define NEGATIVE 1
const long SCALING_FACTOR = 1000;
enum boolean {FALSE, TRUE};
void input_error();
class Fraction
{
protected:
long numerator;
long denominator;
double decimal_equivalent;
long integer_part;
long part_numerator;
long part_denominator;
public:
Fraction()
{ numerator = 0; denominator = 1;
part_numerator = 0; part_denominator = 1;
decimal_equivalent = 0.; integer_part = 0;}
Fraction( long num, long denom )
{
numerator = num;
denominator = denom;
decimal_equivalent = (double)numerator/(double)denominator;
part_numerator = 0; part_denominator = 1;
integer_part = 0;
}
Fraction( double decimal )
{
numerator = (long) (SCALING_FACTOR * decimal);
denominator = SCALING_FACTOR;
decimal_equivalent = decimal;
part_numerator = 0; part_denominator = 1;
integer_part = 0;
}
void show()
{
cout << "The result: "
<< numerator << SLASH << denominator << endl;
if( integer_part )
{
cout << "Converted to a mixed number: " << integer_part;
if( part_numerator )
cout << "-" << part_numerator << SLASH << part_denominator
<< endl;
}
cout << "Decimal equivalent = " << decimal_equivalent << endl;
}
Fraction operator + (Fraction fr) // addition
{
long num, denom;
if( denominator == fr.denominator )
{
num = numerator + fr.numerator;
denom = denominator;
}
else
{
num = numerator * fr.denominator
+ fr.numerator * denominator;
denom = denominator * fr.denominator;
}
return ( Fraction(num,denom) );
}
Fraction operator - (Fraction fr) // subtraction
{
long num, denom;
if( denominator == fr.denominator )
{
num = numerator - fr.numerator;
denom = denominator;
}
else
{
num = numerator * fr.denominator
- fr.numerator * denominator;
denom = denominator * fr.denominator;
}
return ( Fraction(num,denom) );
}
Fraction operator * (Fraction fr) // multiplication
{
long num = numerator * fr.numerator;
long denom = denominator * fr.denominator;
return ( Fraction(num,denom) );
}
Fraction operator / (Fraction fr) // division
{
long num = numerator * fr.denominator;
long denom = denominator * fr.numerator;
return ( Fraction(num,denom) );
}
Fraction parse( char * );
boolean isfactor( long, long );
long gcf( long, long );
void reduce();
void improper_to_proper();
void proper_to_improper();
};
boolean Fraction::isfactor( long number, long factor )
{
if( !(number % factor) )
return (TRUE);
else
return (FALSE);
}
long Fraction::gcf( long num, long denom )
{
long smaller,
larger,
temp;
larger = MAXIMUM(num,denom);
smaller = temp = (num==larger) ? denom : num;
while( temp )
if( isfactor( smaller, temp ) && isfactor( larger, temp ) )
break;
else
temp--;
return (temp);
}
void Fraction::reduce()
{
long temp;
int sign = POSITIVE;
if( numerator < 0) //negative fraction
{ sign = NEGATIVE; numerator *= -1; }
while( (temp = gcf( numerator, denominator ) ) >1 )
{ numerator /= temp; denominator /= temp; }
if( sign )
numerator *= -1; //change back to negative
return;
}
void Fraction::improper_to_proper()
{
if( labs(numerator) >= denominator )
{
integer_part = numerator / denominator;
part_numerator = labs( numerator - denominator * integer_part) ;
part_denominator = denominator;
}
else
{
integer_part = 0;
part_numerator = numerator;
part_denominator = denominator;
}
}
void Fraction::proper_to_improper()
{ numerator = numerator + integer_part*denominator; }
Fraction Fraction::parse( char *token )
{
char *denom_ptr,
*dash_ptr;
Fraction temp;
if ( (dash_ptr = strchr( ++token, DASH )) != NULL )
// skip 1st char., in case minus sign...
{
temp.integer_part = atol( --token ); // renormalize
token = ++dash_ptr;
}
else --token; // renormalize
if( (denom_ptr = strchr( token, SLASH )) != NULL )
{
temp.numerator = atol( token );
temp.denominator = atol( ++denom_ptr );
temp.proper_to_improper();
temp.decimal_equivalent =
(double)temp.numerator/(double)temp.denominator;
}
else
temp = atof( token );
return (temp);
}
Fraction operation_on( Fraction& t1, Fraction& t2, char oper )
{
Fraction temp;
switch (oper)
{
case '+':
temp = t1 + t2;
break;
case '-':
temp = t1 - t2;
break;
case '*':
temp = t1 * t2;
break;
case '/':
temp = t1 / t2;
break;
default:
input_error();
exit( OPERATOR_ERROR );
}
return (temp) ;
}
void main( int argc, char* argv[] )
{
Fraction term1,
term2,
result;
if( argc != ARGCOUNT )
input_error();
term1 = term1.parse( TERM1 );
term2 = term2.parse( TERM2 );
result = operation_on( term1, term2, OP );
result.reduce();
result.improper_to_proper();
result.show();
}
void input_error()
{
cout << endl
<< "Format: fraction aaa/bbb <operator> ccc/ddd" << endl
<< " or" << endl
<< " AAA-aaa/bbb <operator> CCC-ccc/ddd" << endl;
exit( WRONG_NO_OF_ARGS );
}